﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace Foundation.Converters
{
    /// <summary>
    /// Boolean Converter.
    /// </summary>
    public class BooleanConverter : DependencyObject, IValueConverter
    {
        public static readonly DependencyProperty OnTrueProperty =
            DependencyProperty.Register("OnTrue", typeof (object), typeof (BooleanConverter),
                                        new PropertyMetadata(default(object)));

        public static readonly DependencyProperty OnFalseProperty =
            DependencyProperty.Register("OnFalse", typeof (object), typeof (BooleanConverter),
                                        new PropertyMetadata(default(object)));

        public static readonly DependencyProperty OnNullProperty =
            DependencyProperty.Register("OnNull", typeof (object), typeof (BooleanConverter),
                                        new PropertyMetadata(default(object)));

        /// <summary>
        /// Gets or sets the on true.
        /// </summary>
        /// <value>
        /// The on true.
        /// </value>

        public object OnTrue
        {
            get { return GetValue(OnTrueProperty); }
            set { SetValue(OnTrueProperty, value); }
        }

        /// <summary>
        /// Gets or sets the on false.
        /// </summary>
        /// <value>
        /// The on false.
        /// </value>
        public object OnFalse
        {
            get { return GetValue(OnFalseProperty); }
            set { SetValue(OnFalseProperty, value); }
        }

        /// <summary>
        /// Gets or sets the on null.
        /// </summary>
        /// <value>
        /// The on null.
        /// </value>
        public object OnNull
        {
            get { return GetValue(OnNullProperty); }
            set { SetValue(OnNullProperty, value); }
        }

        /// <summary>
        /// Converts a value.
        /// </summary>
        /// <param name="value">The value produced by the binding source.</param>
        /// <param name="targetType">The type of the binding target property.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// A converted value. If the method returns null, the valid null value is used.
        /// </returns>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            value = value == null
                        ? OnNull ?? Default(targetType)
                        : (value.ToString().ToLower() == false.ToString().ToLower() ? OnFalse : OnTrue);
            return value;
        }

        /// <summary>
        /// Converts a value.
        /// </summary>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// A converted value. If the method returns null, the valid null value is used.
        /// </returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == OnNull) return Default(targetType);
            if (value == OnFalse) return false;
            if (value == OnTrue) return true;
            if (value == null) return null;
            if (OnNull != null && value.ToString().ToLower() == OnNull.ToString().ToLower()) return Default(targetType);
            if (OnFalse != null && value.ToString().ToLower() == OnFalse.ToString().ToLower()) return false;
            if (OnTrue != null && value.ToString().ToLower() == OnTrue.ToString().ToLower()) return true;
            return null;
        }

        public static object Default(Type type)
        {
            return type.IsValueType ? Activator.CreateInstance(type) : null;
        }
    }
}


